// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module h_upscaler 
(
    //
    input  wire          I_upscale_clk,    // 165M
    input  wire          I_rst_n,
    // input video
    input  wire          I_vin_pclk,       // slower clk
    input  wire          I_vin_vsync,
    input  wire          I_vin_de,
    input  wire [ 23: 0] I_vin_data,
    // upscaled video
    output reg           O_upscale_new_frame,
    output wire [ 23: 0] O_upscale_data,
    output wire          O_upscale_data_valid,
    output wire          O_upscale_even_line,
    // regfile
    input  wire [ 11: 0] I_reg_vin_width,
    input  wire [ 11: 0] I_reg_upscale_width

);

/******************************************************************************
                                <localparams>
******************************************************************************/

/******************************************************************************
                              <internal signals>
******************************************************************************/
reg  vsync_polar;
reg  [ 2: 0] vsync_sync;
reg  [ 1: 0] vsync_dly;
reg  new_frame;
wire [ 23: 0] fifo_q;
wire fifo_rdreq;
wire [ 11: 0] fifo_usedw;
wire fifo_empty;

/******************************************************************************
                                <module body>
******************************************************************************/
//--------------------------------------------------------------------
// I_vin_pclk clock domain
//--------------------------------------------------------------------
always @ (posedge I_vin_pclk)
    if (I_vin_de)
        vsync_polar <= I_vin_vsync;

//--------------------------------------------------------------------
// async fifo
//--------------------------------------------------------------------
async_fifo_2048x24 u_async_fifo_2048x24(
    .aclr(new_frame),
    .data(I_vin_data),
    .rdclk(I_upscale_clk),
    .rdreq(fifo_rdreq),
    .wrclk(I_vin_pclk),
    .wrreq(I_vin_de),
    .q(fifo_q),
    .rdempty(fifo_empty),
    .rdusedw(fifo_usedw),
    .wrfull()
);

//--------------------------------------------------------------------
// I_upscale_clk clock domain
//--------------------------------------------------------------------
always @ (posedge I_upscale_clk)
    begin
    vsync_sync <= {vsync_sync[1:0], I_vin_vsync};
    vsync_dly <= {vsync_dly[0],vsync_sync[2]};
    end

always @ (posedge I_upscale_clk)
    new_frame <= vsync_polar ? (vsync_dly == 2'b10): (vsync_dly == 2'b01);

always @ (posedge I_upscale_clk) begin
    O_upscale_new_frame <= new_frame;
end

h_upscaler_core u_h_upscaler_core(
    .I_sclk(I_upscale_clk),
    .I_rst_n(I_rst_n),
    .I_new_frame(new_frame),
    .I_fifo_q(fifo_q),
    .O_fifo_rdreq(fifo_rdreq),
    .I_fifo_empty(fifo_empty),
    .I_fifo_usedw(fifo_usedw),
    .O_data_out(O_upscale_data),
    .O_data_out_valid(O_upscale_data_valid),
    .O_upscale_even_line(O_upscale_even_line),
    .I_reg_vin_width(I_reg_vin_width),
    .I_reg_upscale_width(I_reg_upscale_width)
);

endmodule
`default_nettype wire

